Skip to main content

Data Privacy Manager & SFMC custom subscription center to manage your subscribers’s consents

In this article, I will be covering a way to manage your contact’s consents on Marketing Cloud when connected to Sales/Service Cloud.

There is a lot of ways to be GDPR compliant on Salesforce. You can implement the whole process, or save yourself the headaches and use a plugin.

We are going to cover basically the SFMC part on how the plugin Data Privacy Manager app can be used to manage contacts consents on both Sales and Marketing clouds. I’m not going deep on details on the Sales Cloud part, I assume that its pretty simple to plug the app to your system.

How are consents stored in Sales Cloud?

Data Privacy Manager plugin provides data privacy tracking for each type of communication for leads, contacts and person accounts.

The application uses a field on each object to track consents. Each consent is represented by a unique auto-generated six digit code. These values are concatenated into the field and separated by a comma.

example

If we have two types of communications for our contacts, let’s call them Newsletter and SpecialOffers, they will have the ids 100001 & 100002.

We’re going to use a custom field on each object, let’s stick with the app’s recommendation and call it datapm__CommunicationRules__c_.

How are subscriptions handled on SFMC?

Usually, we use the standard fields on Sales/Service Cloud to manage consents (HasOptedOutOfEmail). But sometimes, especially when the context is a little more complex than that, we need to have a lot of channels/consents. Which means we need a custom way to manage our consents.

Therefore, we no longer need to rely on the connector to send back unsubscribes from SFMC to Sales/Service Cloud. Which means, we no longer need to use the UnsubEvent to log unsubscribes.

The UnsubEvent, what is it?

To unsubscribe a contact/lead/person account from AllSubscribers, we need to log an UnsubEvent. It is essential to the proper working and tracking of unsubscribers on SFMC if you are using the standard fields to manage consents (HasOptedOutOfEmail). Creating the UnsubEvent will update the subscriber’s status on AllSub and send back this information to our Sales/Service Cloud org through the Marketing Cloud Connector.

Manage subscribers status outside of AllSubscribers

You may ask, if we are not using standard fields and AllSubscribers to manage consents, how are we going to do it? We need to move the complexity to a Data Extension. Depending on your architecture, you may need more than one.

Consents from Sales Cloud to SFMC

Setup the data extension

First of all, we need a data extension to store our contact’s consents. Each consent will be represented by a boolean field. A True value means we have the contact’s consent to receive that type of emails. A False value means the contact has not given his consent or has unsubscribed.

Here is a reference to the data extension we will be calling Consents. This is a very simple version of the data extension:

Field NameField TypeLengthDefault Value
SubscriberKeyText18
NewsletterEmail_ConsentBooleanFalseFalse
SpecialOffersEmail_ConsentBooleanFalseFalse
caution

We need to give a default value to our boolean fields so that by default, if we don’t have the information about a contact’s consent, we don’t send him anything.

As explained before, consents are concatenated in datapm__CommunicationRules__c_ field and separated by a comma. Each consent is represented by a unique id. We need an SQL query to parse the ids and update the booleans in our data extension. It should look like this:

SELECT

CT.Id AS SubscriberKey,

CASE
WHEN CT.datapm__CommunicationRules__c LIKE '%100001%' THEN 'TRUE'
ELSE 'FALSE'
END AS NewsletterEmail_Consent,

CASE
WHEN CT.datapm__CommunicationRules__c LIKE '%100002%' THEN 'TRUE'
ELSE 'FALSE'
END AS SpecialOffersEmail_Consent

FROM Contact_Salesforce

The query uses two CASE statements to look for the consents ids, if the id is found, the field is populated with a True which means we have the person’s consent to receive that type of communication. It will be set to update the Consent data extension.

Nothing fancy until now, the process seems simple and pretty straightforward.

Now, you should be asking, how are we sending back unsubscribes to Sales Cloud?

Setup the CloudPage

info

Data Privacy Manager provides a simple way to add permissions or unsubscribe a contact, lead or person account by creating a Task with specific texts in the subject and comments fields.

Let’s build a one-click unsubscribe cloud page for contacts. The page will unsubscribe the contact from Newsletter communications.

First, we need get the emailaddr and subscriberkey values from the context. Then, we need to get the contact’s consent from our data extension because we don’t want to make an update if the contact has already visited the page and asked to be unsubscribed:

%%[

SET @emailaddr = AttributeValue("emailaddr")

SET @subKey = AttributeValue("_subscriberkey")

/* Get the NewsletterEmail_Consent value from Consents Data Extension */

SET @rowsConsents = LookupRows("Consents", "SubscriberKey", @subKey)

IF RowCount(@rowsConsents) > 0 then

SET @consentRow = Row(@rowsConsents,1)

SET @newsletterEmail_Consent = Field(@consentRow, "NewsletterEmail_Consent")

ENDIF

]%%

Next, we need to create a Task using the CreateSalesforceObject function. The object of this Task should be:

'Subject', 'Datapm:Unsubscribe'

And the description should contain the id of the consent from which we want the contact to be unsubscribed. In this case, let’s say it is 100001:

'Description', '{"crCode":"100001"}'

The function should look like below. We use the WhoId to identify the contact to whom the Task will be affected. Then, we add the subject and the description as explained.

CreateSalesforceObject('Task',4,'WhoId', @subKey, 'Subject', 'Datapm:Unsubscribe', 'Description', '{"crCode":"100001"}', 'ActivityDate', @timeNow)
note

More fields may be needed depending on your implementation on Sales Cloud (mandatory fields on the Task object).

Now let’s take a look at the function with all the parameters:

%%[

/* Check if the contact is subscribed to the newsletterEmail_Consent */

IF (@newsletterEmail_Consent != 'False') THEN

SET @timeNow = FormatDate(Now(),"iso")

SET @created_taskId= CreateSalesforceObject('Task',4,'WhoId', @subKey, 'Subject', 'Datapm:Unsubscribe', 'Description', '{"crCode":"100001"}', 'ActivityDate', @timeNow)

/* Update Consents Data Extension */

UpsertData("Consents", 1, "SubscriberKey", @subKey, "NewsletterEmail_Consent", "False")

ENDIF

]%%

Let’s take a look at the full script. We have used Bootstrap to make it look beautiful and responsive. Also, we’ve added a confirmation message.

<!doctype html>
<html>
<head>

<meta charset="utf-8">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Unsubscribe - Newsletter</title>

<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Bootstrap -->
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">

<style>
body {
font-family: 'Montserrat', sans-serif;
color: #412761
}
</style>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
%%[

SET @emailaddr = AttributeValue("emailaddr")
SET @subKey = AttributeValue("_subscriberkey")

/* Get the NewsletterEmail_Consent value from Consents Data Extension */
SET @rowsConsents = LookupRows("Consents", "SubscriberKey", @subKey)
IF RowCount(@rowsConsents) > 0 then
SET @consentRow = Row(@rowsConsents,1)
SET @newsletterEmail_Consent = Field(@consentRow, "NewsletterEmail_Consent")
ENDIF

/* Check if the contact is subscribed to the newsletterEmail_Consent */
IF (@newsletterEmail_Consent != 'False') THEN
SET @timeNow = FormatDate(Now(),"iso")
SET @created_taskId= CreateSalesforceObject('Task',4,'WhoId', @subKey, 'Subject', 'Datapm:Unsubscribe', 'Description', '{"crCode":"100001"}', 'ActivityDate', @timeNow)

/* Update Consents Data Extension */
UpsertData("Consents", 1, "SubscriberKey", @subKey, "NewsletterEmail_Consent", "False")
ENDIF
]%%

</head>
<body>
<!-- Logo start-->
<div class="row" style="background-color:#ab5643;">
<div class="col-md-3" style="margin-left:5%;margin-top:1%;margin-bottom:2%;">
<img width="250px" height="100px" src="YOUR_LOGO_LINK" alt="" id="logo"/>
</div>
<div class="col-md-9">
</div>
</div>
<!-- Logo end-->
<!-- body start-->
<div class="row" style="background-color:#ffffff;">
<div class="col-md-3">
</div>
<div class="col-md-6" >
<h3 style="margin:3%;margin-top: 20%;margin-bottom: 20%;">Sorry to see you go, the email %%=v(@emailaddr)=%% has been unsubscribed from our Newsletter. It will be effective in 48 hours.
</h3>
</div>
<div class="col-md-3">
</div>
</div>
<!-- body end-->
</body>
</html>

Unsubscribe a contact from all communications

You might ask, what if we want to unsubscribe a contact from all communications and channels at once?

Data Privacy Manager got you covered. There is no need to make multiple CreateSalesforceObject calls. All we need to do is make some changes on the subject's and comment's contents.

Let’s say we want to unsubscribe a contact from all channels and communications at once, the subject should look like:

Datapm:Optout

And the comment field should be like:

{}

And if we want to unsubscribe the contact from all consents of a specific channel, we need to add the channels name in the comment’s field. In this case, the contact will be unsubscribed from all emails:

{"channel":"email"}

Don't hesitate to drop me a message/email if you have any questions/remarks, I’ll be happy to answer them.